﻿using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace LitTools
{
    public class CreateScriptUtility
    {
        public static void SaveScript(string scriptPath, string scriptName, ScriptInfo scriptInfo)
        {
            string folderPath = Application.dataPath + "/" + scriptPath;
            string fullPath = folderPath + "/" + scriptName + ".cs";
            Directory.CreateDirectory(folderPath);
            if (!File.Exists(fullPath))
            {
                FileStream fs = File.Create(fullPath);
                fs.Close();
            }
            File.WriteAllText(fullPath, scriptInfo.GetContentString());
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }

    public struct ScriptInfo
    {
        /// <summary>
        /// 所在命名空间
        /// </summary>
        public string namespaceName;
        /// <summary>
        /// 使用命名空间列表
        /// </summary>
        public List<string> useNamespaceList;
        /// <summary>
        /// 脚本中的类
        /// </summary>
        public List<ClassInfo> classList;

        public string GetContentString()
        {
            StringBuilder result = new StringBuilder();
            result.Append("//本脚本由程序化自动生成，不可以手动修改\n");
            for (int i = 0; i < useNamespaceList.Count; i++)
            {
                result.Append($"using {useNamespaceList[i]};\n");
            }
            result.Append($"namespace {namespaceName}\n");
            result.Append("{\n");
            for (int i = 0; i < classList.Count; i++)
            {
                result.Append(classList[i].GetContentString());
            }
            result.Append("}");
            return result.ToString();
        }
    }

    public struct ClassInfo
    {
        /// <summary>
        /// 脚本名
        /// </summary>
        public string className;
        /// <summary>
        /// 父类名
        /// </summary>
        public string parentClassName;
        public List<VariableInfo> variableList;
        public List<MethodInfo> methodList;
        public string GetContentString()
        {
            StringBuilder result = new StringBuilder();
            result.Append($"    public class {className}");
            if (string.IsNullOrEmpty(parentClassName))
                result.Append("\n");
            else
                result.Append($" : {parentClassName}\n");
            result.Append("    {\n");
            if (variableList != null)
                for (int i = 0; i < variableList.Count; i++)
                {
                    result.Append(variableList[i].GetContentString());
                }
            if (methodList != null)
                for (int i = 0; i < methodList.Count; i++)
                {
                    result.Append(methodList[i].GetContentString());
                }
            result.Append("\n    }\n");
            return result.ToString();
        }
    }

    public struct VariableInfo
    {
        public VisitorType visitorType;
        public string decorator;
        public string varType;
        public string varName;
        public string defaultValue;

        public string GetContentString()
        {
            string result = $"        {visitorType.ToString().ToLower()} {decorator} {varType} {varName}";
            if (string.IsNullOrEmpty(defaultValue))
                result += ";\n";
            else
                result += $"= {defaultValue};\n";
            return result;
        }
    }

    public struct MethodInfo
    {
        public VisitorType visitorType;
        public string methodName;
        public string methodBack;
        public List<string> methodContent;
        public List<MethodPar> parList;
        public string GetContentString()
        {
            StringBuilder result = new StringBuilder();
            result.Append($"        {visitorType.ToString().ToLower()} {methodBack} {methodName}(");
            if (parList == null || parList.Count == 0)
            {
                result.Append(")\n");
            }
            else
            {
                for (int i = 0; i < parList.Count; i++)
                {
                    if (i > 0)
                        result.Append(", ");
                    result.Append(parList[i].GetContentString());
                }
                result.Append(")\n");
            }
            result.Append("        {\n");
            foreach (var item in methodContent)
            {
                result.Append("            " + item + "\n");
            }
            result.Append("        }");
            return result.ToString();
        }
    }

    public struct MethodPar
    {
        public string parType;
        public string parName;

        public string GetContentString()
        {
            return $"{parType} {parName}";
        }
    }

    public enum VisitorType
    {
        None = 0,
        Private = 1,
        Protected = 2,
        Public = 3,
    }
}